﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Nature.Toolkit.GKin
{
    /// <summary>
    /// 
    /// </summary>
    public abstract class TPYSoneSolver :
        Nature.Numerics.ISoneFunction,
        Nature.Numerics.ISoneVariableCorrection
    {
        protected abstract void Compute(ReadOnlyIdealGasMixture variable, TPYVector function);

        private IdealGasMixture m_mixture;
        private TPYVector m_vector;
        private Numerics.Basic.SoneNewton<TPYSoneSolver> m_solver;
        private object m_anchor;

        protected TPYSoneSolver(ModelObject model)
        {
            this.Model = model;
            m_mixture = model.CreateIdealGasMixture();
            m_solver = new Numerics.Basic.SoneNewton<TPYSoneSolver>(this);
            m_vector = new TPYVector(model.Nsp);
            m_solver.SetRelativeConvergenceRadius(5.0e-2);
            m_solver.SetRelativeTolerance(1.0e-5);
        }

        protected ModelObject Model
        {
            get;
            private set;
        }

        protected void Solve(IdealGasMixture mixture)
        {
            m_vector.CopyFrom(mixture);
            m_solver.Solve(m_vector, ref m_anchor);
            m_vector.CopyTo(mixture);
        }

        #region ISoneFunction Members

        int Numerics.ISoneFunction.Nva
        {
            get { return m_mixture.Nsp + 2; }
        }

        void Numerics.ISoneFunction.Compute(double[] x, double[] y)
        {
            TPYVector vector = x;
            m_mixture.UpdateTPY(vector.T, vector.P, vector.Y);
            this.Compute(new ReadOnlyIdealGasMixture(m_mixture), new TPYVector(y));
        }

        #endregion

        #region ISoneVariableCorrection Members

        void Numerics.ISoneVariableCorrection.ApplyCorrection(double[] x)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

}
